﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public delegate void GetRiginalBody2d(Rigidbody2D rig2d);
public delegate void GetCollider2d(BoxCollider2D collder2d);
public class ActorHuman : ActorBase, ICmdReader, IBackFirer,IGunCarrier,ISparker
{
    // ----- 角色运动属性 -----
    public float walkSpeedValue_ = 1;
    public float jumpSpeedValue_ = 8;


    // ----- 当前帧角色运动数据 -----
    protected float xMoveVec_ = 0;
    protected float yMoveVec_ = 0;

    protected float xDeBuffVec_ = 0;


    // ----- 当前朝向 -----
    private EMoveOri nowMoveOri_ = EMoveOri.E_RIGHT;
    public EMoveOri NowMoveOri {
        get {
            return this.nowMoveOri_;
        }
    }



    // ----- 依赖 rigid -----
    public Rigidbody2D Rig2d_ = null;


    // ----- 依赖运动状态 -----
    private IMotionState state_ = null;
    public IMotionState MotionState {
        set { this.state_ = value; }
        get {
            if (this.state_ == null) {
                Debug.LogError("MotionState == null");
                return null;
            }
            return this.state_;
        }
    }

    // ----- 依赖运动执行器 -----
    public ActionProcesser ActProcesser = null;




    // ----- 处理命令 -----
    private CmdBase[] arrCmds_ = new CmdBase[3];
    public void SendCmd(CmdBase cmd)
    {
        arrCmds_[cmd.Type] = cmd;
    }
    private void updateByCmds() {
        var moveCmd = arrCmds_[CmdBase.TYPE_MOVE];
        if (moveCmd != null) {
            if ((moveCmd as CmdMove).Oir ==  CmdMove.ORI_LEFT) {
                this.walkLeft();
            } else if((moveCmd as CmdMove).Oir == CmdMove.ORI_RIGHT)
            {
                this.walkRight();
            }
        }

        var jumpCmd = arrCmds_[CmdBase.TYPE_JUMP];
        if (jumpCmd != null) {
            this.jump();
        }

        var fireCmd = arrCmds_[CmdBase.TYPE_FIRE];
        if (fireCmd != null) {
            this.fire();
        }
        var count = arrCmds_.Length;
        for (var i = 0;i<count;++i) {
            arrCmds_[i] = null;
        }
    }


    // ----- 处理更新 -----
    private void updateByBuff() {

    }
    private void clearTmpData() {
        this.xMoveVec_ = 0;
        this.yMoveVec_ = 0;
       // this.xDeBuffVec_ = 0;
    }
    protected virtual void updateDataToUnityComponents() {
        Rig2d_.velocity = new Vector2(xMoveVec_ + xDeBuffVec_, Rig2d_.velocity.y + yMoveVec_);
    }

    // Update is called once per frame
    void Update()
    {
        this.clearTmpData();
        this.updateByCmds();
        this.updateDataToUnityComponents();
    }


    // ----- 处理行为表现 -----
    protected virtual void walkRight() {
        xMoveVec_ = walkSpeedValue_;
        this.nowMoveOri_ = EMoveOri.E_RIGHT;
        var absScale = Mathf.Abs(this.transform.localScale.x);
        this.transform.localScale = new Vector3(absScale, this.transform.localScale.y, this.transform.localScale.z);
    }
    protected virtual void walkLeft() {
        xMoveVec_ = walkSpeedValue_ * -1;
        this.nowMoveOri_ = EMoveOri.E_LEFT;
        var absScale = Mathf.Abs(this.transform.localScale.x);
        this.transform.localScale = new Vector3(-absScale, this.transform.localScale.y, this.transform.localScale.z);

    }
    protected virtual void jump() {
        if (this.MotionState != null) {
            if (!this.MotionState.IsInAir()) {

                yMoveVec_ = jumpSpeedValue_;
            }
        }
    }
    protected virtual void fire() {
        if (this.gun_ != null) {
            this.gun_.Fire();
        }
    }

    private const int TAG_ACT_SPARK = 1;
    private const int TAG_ACT_BACKFIRE = 2;
    public virtual void Spark(float durtion) {
        this.ActProcesser.StopActionByTag(TAG_ACT_SPARK);
        this.ActProcesser.RunAction(new ActionSpark(this, 0.2f, 0.05f),TAG_ACT_SPARK);
    }
    
    public virtual void BackFire(float startSpeed,float durtion = 0.75f,float lerp = 0.03f) { // 承受后座力
        var oriValue = 0;
        if (this.NowMoveOri == EMoveOri.E_RIGHT) {
            oriValue = -1;
        }
        if (this.NowMoveOri == EMoveOri.E_LEFT) {
            oriValue = 1;

        }
        this.ActProcesser.StopActionByTag(TAG_ACT_BACKFIRE);
        this.ActProcesser.RunAction(new ActionBackFire(this, durtion, lerp, startSpeed * oriValue), TAG_ACT_BACKFIRE);
    }

    public virtual void HitByBullet(float startSpeed, float durtion = 0.75f, float lerp = 0.03f)
    { // 承受后座力
        this.ActProcesser.StopActionByTag(TAG_ACT_BACKFIRE);
        this.ActProcesser.RunAction(new ActionBackFire(this, durtion, lerp, startSpeed ), TAG_ACT_BACKFIRE);
    }


    // public Sprite SpDead = null;
    // public Sprite SpLive = null;
    // public virtual void Dead() {
    //     var spr = this.GetComponent<SpriteRenderer>();
    //     if (spr != null&& this.SpDead != null) {
    //         spr.sprite = this.SpDead;
    //     }
    // }
    //
    // public virtual void Live() {
    //     var rig2d = this.GetComponent<Rigidbody2D>();
    //     rig2d.freezeRotation = false;
    //
    //     var spr = this.GetComponent<SpriteRenderer>();
    //     if (spr != null && this.SpLive != null)
    //     {
    //         spr.sprite = this.SpLive;
    //     }
    // }


    // ----- 实现各种接口 ------

    public void SetHorizonVec(float x)
    {
        this.xDeBuffVec_ = x;
    }

    public float GetHorizonVec()
    {
        return this.xDeBuffVec_;
    }

    public Vector2 GetPosition()
    {
        return transform.localPosition;
    }

    public Vector2 GetSize()
    {
        return new Vector2(50,50);
    }

    public EMoveOri GetOri()
    {
        return this.NowMoveOri;
    }


    public Material DefaultMaterial = null;
    public Material SparkMaterial = null;
    public void TurnNormal()
    {
        var spr = this.GetComponent<SpriteRenderer>();
        if (spr != null && DefaultMaterial != null) {
            spr.material = this.DefaultMaterial;
        }
    }

    public void TurnSpark()
    {
        var spr = this.GetComponent<SpriteRenderer>();
        if (spr != null&& SparkMaterial != null)
        {
            spr.material = this.SparkMaterial;
        }
    }


    public SpriteRenderer SprOfGun = null;
    private GunBase gun_ = null;
    public void SetGun(GunBase g)
    {
        gun_ = g;
        gun_.SetCameraMgr(CameraMgr.GetInstance());
        gun_.SetPrefabsFactory(PrefabsMgr.GetInstance());
        gun_.SetGunCarrier(this);
        if (this.SprOfGun != null && this.gun_!= null) {
            if (this.gun_.SpOfGun!= null)
            {
                this.SprOfGun.sprite = this.gun_.SpOfGun;
            }
        }
    }

}
